package tij4.polymorphism.exercise.ex13;

/*
    在ReferenceCounting.java 中添加一个finalize()方法,用来校验中止条件
 */

class Shared {
    private int refcount = 0;
    private static long counter = 0;
    private final long id = counter++;

    public Shared() {
        System.out.println("Creating " + this);
    }
    public void addRef() {
        refcount++;
    }

    @Override
    public String toString() {
        return "Shared " + id;
    }
    protected boolean dispose() {
        if (--refcount == 0) {
            System.out.println("Disposing " + this);
            return true;
        }
        return false;
    }
    //答案
    protected void finalize() {
        if(refcount > 0)
            System.out.println("Error: " + refcount + " Shared " + id + " objects in use");
    }
}

class Composing {
    private Shared shared;
    private static long counter = 0;
    private final long id = counter++;

    public Composing(Shared shared) {
        System.out.println("Creating " + this);
        this.shared = shared;
        this.shared.addRef();
    }
    protected void dispose() {
        System.out.println("dispose " + this);
        shared.dispose();
    }

    @Override
    public String toString() {
        return "Composing " + id;
    }
}

public class ReferenceCounting {
    public static void main(String[] args) {
        Shared shared = new Shared();
        Composing[] composings = {
                new Composing(shared), new Composing(shared), new Composing(shared),
                new Composing(shared), new Composing(shared)
        };
        //foreach 按创建时的顺序去除数据
//        for (Composing composing : composings) {
//            composing.dispose();
//        }

        for(Composing c : composings)
            c.dispose();
        //答案
        Composing compTest = new Composing(shared);
        Composing compTest2 = new Composing(shared);
        // Test finalize():
        shared.finalize();  //显式调用finalize方法
        Shared sharedTest = new Shared();
        Composing compTest3 = new Composing(sharedTest);
        // Test sharedTest finalize():
        sharedTest.finalize();

//自己做的
//        composings[2].dispose();
//        shared.dispose();
//        try {
//            new ReferenceCounting().finalize();
//        }catch (Throwable e) {
//            System.out.println(e.getMessage());
//        }
//    }
//    @Override
//    protected void finalize() throws Throwable {
//        Shared shared = new Shared();
//        if (!shared.dispose()) {
//            throw new RuntimeException("Shared对象还被引用着");
//        }
    }
}
